package com.mi.easyexceldemo.utils;

import com.alibaba.fastjson.JSON;
import com.mi.easyexceldemo.constants.ComConstants;
import com.mi.easyexceldemo.enums.NormalEnum;
import com.mi.easyexceldemo.enums.SourceEnum;
import com.mi.easyexceldemo.exception.GlobalException;
import com.mi.easyexceldemo.vo.People;
import org.apache.commons.lang3.StringUtils;

import javax.validation.ValidationException;
import java.lang.reflect.Field;
import java.util.*;

public class CommonUtil {
    private static boolean isRowEmpty(List<String> row) {
        for (int i = 0; i < row.size(); i++) {
            if (StringUtils.isNotBlank(row.get(i))) {
                return false;
            }
        }
        return true;
    }

    public static <T> Map<String, Object> convertImportData(String filePath,
                                                            Map<String, String[]> checkRules, String[] fieldNames, Class<T> clazz) throws Exception {

        Map<String, Object> resultMap = new HashMap<>(4);
        List<List<String>> rowList = ExcelUtil.getExcelData(filePath);
        int allCount = ExcelUtil.getImportExcelColumnCount(filePath);
        List<T> entityList = new ArrayList<>();
        if (rowList.size() == 0) {
            resultMap.put("msg", "导入文件内容为空");
            resultMap.put("chkflg", false);
            resultMap.put("entityList", entityList);
            return resultMap;
        }

        Set<String> requireFieldSet = new HashSet<>(Arrays.asList(checkRules.get("requireField")));
        Set<String> dateFieldSet = new HashSet<>(Arrays.asList(checkRules.get("dateField")));
        Set<String> nonRepeatFieldSet = new HashSet<>(Arrays.asList(checkRules.get("nonRepeat")));
        Set<String> dictFieldSet = new HashSet<>(Arrays.asList(checkRules.get("dictField")));
        Set<String> repeatValues = new HashSet<>();
        boolean chkflg = true, parse = true;

        Set<String> errRowSet = new HashSet<>();

        StringBuffer msg = new StringBuffer();
        T entity;
        List<String> row;
        String cell, field;
        Calendar calendar = Calendar.getInstance(Locale.CHINA);
        for (int r = 0; r < rowList.size(); r++) {
            row = rowList.get(r);

            if (row.size() < allCount) {
                // 说明内容结尾不够，有为空的
                int addNum = allCount - row.size();
                for (int i = 0; i < addNum; i++) {
                    row.add("");
                }
            }

            if (isRowEmpty(row)) {
                continue;
            }
            entity = clazz.newInstance();
            ReflectionUtils.setFieldValue(entity, "createDate", new Date());
            for (int i = 0; i < row.size(); i++) {
                String errKey = String.format("%s,%s", r + 2, i + 1);
                if (fieldNames.length <= i) {
                    continue;
                }
                cell = row.get(i);
                field = fieldNames[i];
                //临时增加对身份证校验
                if (entity instanceof People) {
                    if (StringUtils.equals(field, "cardCode") && StringUtils.length(cell) != 18) {
                        chkflg = false;
                        if (!errRowSet.contains(errKey)) {
                            msg.append(String.format("%s行%s列，单元格内容解析错误，请输入正确的身份证；", r + 2, i + 1));
                            errRowSet.add(errKey);
                        }
                    }
                }
                // 必填项校验
                if (requireFieldSet.contains(field) && StringUtils.isBlank(cell)) {
                    if (!errRowSet.contains(errKey)) {
                        errRowSet.add(errKey);
                        msg.append(String.format("%s行%s列，单元格内容不能为空；", r + 2, i + 1));
                    }
                    chkflg = false;
                }
                // 日期格式校验
                if (dateFieldSet.contains(field) && StringUtils.isNotBlank(cell)) {
                    cell = DateStringUtil.complementTime(cell);
                    if (DateStringUtil.isNotDate(cell)) {
                        if (!errRowSet.contains(errKey)) {
                            errRowSet.add(errKey);
                            msg.append(String.format("%s行%s列，单元格内容应该为日期格式；", r + 2, i + 1));
                        }
                        chkflg = false;
                    } else {
                        cell = DateStringUtil.getFormatDateString(cell, null);
                    }
                }
                // 字典字段校验，cell内容是否为字典项名称
                if (dictFieldSet.contains(field)) {
                    switch (field) {
                        case "address":
                            if (null == SourceEnum.select(cell)) {
                                if (!errRowSet.contains(errKey)) {
                                    errRowSet.add(errKey);
                                    msg.append(String.format("%s行%s列，单元格内容应该为%s其中之一；", r + 2, i + 1,
                                            Arrays.toString(SourceEnum.getNameArray())));
                                }
                                chkflg = false;
                            }
                            break;
                        default:
                            if (null == NormalEnum.select(cell) && null == NormalEnum
                                    .getByName(cell)) {
                                if (!errRowSet.contains(errKey)) {
                                    errRowSet.add(errKey);
                                    msg.append(String.format("%s行%s列，单元格内容应该为%s其中之一；", r + 2, i + 1,
                                            Arrays.toString(NormalEnum.getNameArray())));
                                }
                                chkflg = false;
                            }
                            break;
                    }
                }

                // 不可重复字段校验
                if (nonRepeatFieldSet.contains(field)) {
                    if (repeatValues.contains(cell)) {
                        if (!errRowSet.contains(errKey)) {
                            errRowSet.add(errKey);
                            msg.append(String.format("%s行%s列，单元格内容重复；", r + 2, i + 1));
                        }
                        chkflg = false;
                    } else {
                        repeatValues.add(cell);
                    }
                }
                if (chkflg) {
                    try {
                        Object value = ExcelUtil.convertToObject(entity, field, cell);
                        ReflectionUtils.setFieldValue(entity, field, value);
                    }catch (Exception e) {
                        parse = false;
                        String errorMessage = "";
                        if (e instanceof ValidationException) {
                            errorMessage = JSON.parseObject(e.getMessage()).getString(field);
                        } else if (e instanceof GlobalException) {
                            errorMessage = e.getMessage();
                        }
                        if (!errRowSet.contains(errKey)) {
                            errRowSet.add(errKey);
                            msg.append(String.format("%s行%s列，单元格内容解析错误,%s；", r + 2, i + 1, errorMessage));
                        }
                    }
                }
            }
            //添加创建时间
            ReflectionUtils.setFieldValue(entity, "createDate", calendar.getTime());
            entityList.add(entity);
        }
        //如果parse为true，意味着解析没有发生异常，则正常返回chkflg，如果为假，则发生异常，返回parse
        resultMap.put("chkflg", parse ? chkflg : parse);
        resultMap.put("msg", msg.toString());
        resultMap.put("entityList", entityList);
        return resultMap;
    }
}
